package com.we823.project.controller.repo;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.we823.project.common.utils.CodeGenerate;
import com.we823.project.common.web.StockUtil;
import com.we823.project.common.web.status.PermissionStatus;
import com.we823.project.common.web.status.StockAction;
import com.we823.project.controller.AbstractBaseController;
import com.we823.project.core.web.WebConstants;
import com.we823.project.model.UserModel;
import com.we823.project.model.product.PlanDetailModel;
import com.we823.project.model.product.ProductTaskModel;
import com.we823.project.model.repo.MaterialModel;
import com.we823.project.model.repo.MaterialStockOutModel;
import com.we823.project.model.repo.StockOutTaskModel;
import com.we823.project.repository.service.UserService;
import com.we823.project.repository.service.product.PlanDetailService;
import com.we823.project.repository.service.product.ProductTaskService;
import com.we823.project.repository.service.repo.MaterialService;
import com.we823.project.repository.service.repo.MaterialStockOutService;
import com.we823.project.repository.service.repo.MaterialStockService;
import com.we823.project.repository.service.repo.StockOutTaskService;
import com.we823.utils.web.RequestUtil;

@Controller
@RequestMapping(WebConstants.REPO_STOCK+"/out")
public class MaterialStockOutController extends AbstractBaseController<MaterialStockOutModel>{

	private String baseUrl = WebConstants.REPO_STOCK_TEMPLATE + "out/";
	
	private MaterialStockOutService materialStockOutService;
	@Autowired
	private MaterialService materialService;
	
	private @Resource UserService userService;
	
	private @Resource PlanDetailService planDetailService;
	private @Resource ProductTaskService productTaskService;
	
	@Autowired
	private MaterialStockService materialStockService;
	
	@Autowired
	private StockOutTaskService stockOutTaskService;
	
	@Autowired
	public MaterialStockOutController(MaterialStockOutService materialStockOutService) {
		super(materialStockOutService);
		this.materialStockOutService = materialStockOutService;
		super.baseUrl = baseUrl;
		setResourceIdentity("repo:stock_out");
	}

	@Override
	public Page<MaterialStockOutModel> getData(PageRequest pageRequest, HttpServletRequest request, Model model, boolean pageable) {
		Page<MaterialStockOutModel> materialStockOutPage = null;
		if(pageable){
			materialStockOutPage = materialStockOutService.findAll(pageRequest);
		}else{
			materialStockOutPage = new PageImpl<>(materialStockOutService.findAll());
		}
		fillInfo(materialStockOutPage);
		return materialStockOutPage;
	}
	
	
	private void fillInfo(Page<MaterialStockOutModel> materialStockOutPage) {
		if(materialStockOutPage!=null) {
			List<MaterialStockOutModel> materialStockOutModels = materialStockOutPage.getContent();
			if (materialStockOutModels!=null && materialStockOutModels.size()>0) {
				
				List<String> materialCodeList = Lists.newArrayList();
				for (MaterialStockOutModel materialStockOutModel : materialStockOutModels) {
					materialCodeList.add(materialStockOutModel.getMaterialCode());
				}
				Map<String, MaterialModel> materialMap = materialService.mapByMaterialCodeList(materialCodeList);
				for (MaterialStockOutModel materialStockOutModel : materialStockOutModels) {
					MaterialModel materialModel = materialMap.get(materialStockOutModel.getMaterialCode());
					if (materialModel!=null) {
						materialStockOutModel.setMaterialName(materialModel.getName());
						String model = materialModel.getFullname();
						if (!StringUtils.isEmpty(materialModel.getColor())) {
							model += "("+materialModel.getColor()+")";
						}
						materialStockOutModel.setModel(model);
					}
					
					Map<Integer, ProductTaskModel> productTaskMap = Maps.newHashMap();
					Map<Integer, PlanDetailModel> planDetailMap = Maps.newHashMap();
					fillPlanDetailInfo(materialStockOutModel,productTaskMap,planDetailMap);
					
				}
			}
		}
		
	}

	/**
	 * 填充计划相关信息
	 * @param materialStockOutModel
	 */
	private void fillPlanDetailInfo(MaterialStockOutModel materialStockOutModel,Map<Integer,ProductTaskModel> productTaskMap,Map<Integer,PlanDetailModel> planDetailMap) {
		if (materialStockOutModel!=null) {
			int id = materialStockOutModel.getId();
			List<StockOutTaskModel> stockOutTaskModels = stockOutTaskService.findByStockOutId(id);
			if (stockOutTaskModels!=null && stockOutTaskModels.size()>0) {
				StockOutTaskModel stockOutTaskModel = stockOutTaskModels.get(0);
				int taskId = stockOutTaskModel.getTaskId();
				ProductTaskModel productTaskModel = productTaskMap.get(taskId);
				
				String taskCode = "";
				String planCode = "";
				
				int planDetailId = 0;
				if (productTaskModel==null) {
					productTaskModel = productTaskService.findOne(taskId);
					if (productTaskModel!=null) {
						productTaskMap.put(productTaskModel.getId(), productTaskModel);
					}
				}
	
				if (productTaskModel!=null) {
					taskCode = productTaskModel.getCode();
					planDetailId=productTaskModel.getPlanDetailId();
				}
				
				if (planDetailId>0) {
					PlanDetailModel planDetailModel = planDetailMap.get(planDetailId);
					if(planDetailModel==null) {
						planDetailModel = planDetailService.findOne(planDetailId);
						if (planDetailModel!=null) {
							planDetailMap.put(planDetailId, planDetailModel);
						}
					}
					if (planDetailModel!=null) {
						planCode = planDetailModel.getPlanCode();
					}
				}
				
				materialStockOutModel.setPlanCode(planCode);
				materialStockOutModel.setTaskCode(taskCode);
			}
		}
		
	}

	@Override
	protected Sort getSort(HttpServletRequest request) {
		return new Sort(Direction.DESC,"id");
	}
	@Override
	public String preAdd(HttpServletRequest request, Model model) {
		model.addAttribute("stockOutCode",CodeGenerate.getMaterialStockOutCode());
		return super.preAdd(request, model);
	}
	@RequestMapping("confirm")
	@ResponseBody
	public Model confirm(HttpServletRequest request,Model model){
		check(PermissionStatus.UPDATE);
		Integer id = RequestUtil.getValueByParam(request, "id", 0);
		String memo = RequestUtil.getValueByParam(request, "memo");
		float finalNum = RequestUtil.getFloatValueByParam(request, "finalNum", 0f);
		if(id>0){
			MaterialStockOutModel materialStockOutModel = materialStockOutService.findOne(id);
			if(materialStockOutModel!=null){
				materialStockOutModel.setFinalNum(finalNum);
				materialStockOutModel.setFlag(1);
				materialStockOutModel.setEdittime(new Date());
				materialStockOutModel.setMemo(memo);
				
				List<StockOutTaskModel> stockOutCardModels = stockOutTaskService.findByStockOutId(id);
				
				materialStockOutService.update(materialStockOutModel);
				model.addAttribute("stockOutCards",stockOutCardModels);
				model.addAttribute("hasError",false);
				
				changeStock(materialStockOutModel);
			}
		}else{
			model.addAttribute("hasError",true);
		}
		return model;
	}
	
	@Override
	public String add(HttpServletRequest request, MaterialStockOutModel entity, Model model, BindingResult bindingResult,RedirectAttributes redirectAttributes) {
		if(entity!=null){
			entity.setFlag(1);
			entity.setNeedNum(entity.getFinalNum());
		}
		String result = super.add(request, entity, model, bindingResult,redirectAttributes);
		Date addtime = entity.getAddtime();
		if(addtime!=null){
			String materialCode = entity.getMaterialCode();
			float totalNum = entity.getFinalNum();
			StockUtil.changeStock(addtime, materialCode, totalNum, StockAction.Out, materialStockService);
		}
		redirectAttributes.addFlashAttribute(WebConstants.MESSAGE, "添加出库信息成功");
		return result;
	}

	@RequestMapping("getOne")
	@ResponseBody
	public Model getOne(HttpServletRequest request,Model model) {
		int id = RequestUtil.getValueByParam(request, "id", 0);
		if(id>0) {
			List<Integer> idList = new ArrayList<>();
			idList.add(id);
			MaterialStockOutModel materialStockOutModel = materialStockOutService.findOne(id);
			if (materialStockOutModel!=null) {
				MaterialModel materialModel = materialService.findByCode(materialStockOutModel.getMaterialCode());
				if (materialModel!=null) {
					materialStockOutModel.setMaterial(materialModel);
					String name = materialModel.getName()+" "+materialModel.getFullname();
					if (!StringUtils.isEmpty(materialModel.getColor())) {
						name += "("+materialModel.getColor()+")";
					}
					materialStockOutModel.setMaterialName(name);
					if (StringUtils.isEmpty(materialStockOutModel.getFinalUnit())) {
						materialStockOutModel.setFinalUnit(materialModel.getUnit());
					}
					
					Map<Integer,ProductTaskModel> productTaskMap = Maps.newHashMap();
					Map<Integer,PlanDetailModel> planDetailMap = Maps.newHashMap();
					fillPlanDetailInfo(materialStockOutModel, productTaskMap, planDetailMap);
					
					int userId = materialStockOutModel.getUserId();
					if (userId>0) {
						UserModel userModel = userService.findOne(userId);
						if (userModel!=null) {
							materialStockOutModel.setUserName(userModel.getRealname());
						}
					}
				}
				model.addAttribute("materialStockOut",materialStockOutModel);
				model.addAttribute("hasError",false);
			}else {
				model.addAttribute("hasError",true);
				model.addAttribute("message","未能找到此记录");
			}
		}else {
			model.addAttribute("hasError",true);
			model.addAttribute("message","记录号错误！");
		}
		return model;
	}
	//修改出库信息
	private void changeStock(MaterialStockOutModel materialStockOutModel) {
		if(materialStockOutModel!=null){
			Date addtime = materialStockOutModel.getAddtime();
			if(addtime!=null){
				String materialCode = materialStockOutModel.getMaterialCode();
				float totalNum = materialStockOutModel.getFinalNum();
				StockUtil.changeStock(addtime, materialCode, totalNum, StockAction.Out, materialStockService);
			}
		}
		
	}

	public StockOutTaskService getStockOutCardService() {
		return stockOutTaskService;
	}

	public void setStockOutCardService(StockOutTaskService stockOutCardService) {
		this.stockOutTaskService = stockOutCardService;
	}

	public MaterialStockService getMaterialStockService() {
		return materialStockService;
	}

	public void setMaterialStockService(MaterialStockService materialStockService) {
		this.materialStockService = materialStockService;
	}

	public MaterialService getMaterialService() {
		return materialService;
	}

	public void setMaterialService(MaterialService materialService) {
		this.materialService = materialService;
	}

	
}
